import * as step from '@flow-step/step-toolkit'
import * as sinon from 'sinon'
import {expect} from 'chai'
import process from 'process'
import {getKubernetesCertificate} from '../src/certificate'

type KubernetesCertificate = {
    type: string,
    kubeConfig: string,
    miranaProxy: string
    jwtToken: string
}

describe('Kubernetes Certificate Function', () => {
    let sandbox: sinon.SinonSandbox
    let processEnv: NodeJS.ProcessEnv
    let getKubernetesCertificateStub: any

    before(() => {
        sandbox = sinon.createSandbox()
        processEnv = process.env

        getKubernetesCertificateStub = sandbox.stub(step.certificate, 'getKubernetesCertificate')
    })

    after(() => {
        sandbox.restore()
        process.env = processEnv
    })

    it('should handle "serviceConnection" authType correctly', async () => {
        process.env.KUBERNETES_CONNECTION_ID = 'mockKubernetesConnectionId'
        process.env.FLOW_JOB_TOKEN = 'mockFlowJobToken'

        const mockCertificate: KubernetesCertificate = {
            type: 'mockType',
            kubeConfig: 'mockKubeConfig',
            miranaProxy: '',
            jwtToken: ''
        }
        getKubernetesCertificateStub.resolves(mockCertificate)

        const certificate = await getKubernetesCertificate()
        sinon.assert.calledWith(getKubernetesCertificateStub, 'mockFlowJobToken', 'mockKubernetesConnectionId')
        expect(certificate).to.deep.equal(mockCertificate)
    })

    it('should throw error when KUBERNETES_CONNECTION_ID is missing', async () => {
        delete process.env.KUBERNETES_CONNECTION_ID
        process.env.FLOW_JOB_TOKEN = 'mockFlowJobToken'

        try {
            await getKubernetesCertificate()
            expect.fail('Expected an error to be thrown')
        } catch (error) {
            // @ts-ignore
            expect(error.message).to.equal('missing KUBERNETES_CONNECTION_ID')
        }
    })

    it('should throw error when FLOW_JOB_TOKEN is missing', async () => {
        process.env.KUBERNETES_CONNECTION_ID = 'mockKubernetesConnectionId'
        delete process.env.FLOW_JOB_TOKEN
        try {
            await getKubernetesCertificate()
            expect.fail('Expected an error to be thrown')
        } catch (error) {
            // @ts-ignore
            expect(error.message).to.equal('missing FLOW_JOB_TOKEN')
        }
    })

    it('should throw error when getKubernetesCertificate returns invalid data', async () => {
        process.env.KUBERNETES_CONNECTION_ID = 'mockKubernetesConnectionId'
        process.env.FLOW_JOB_TOKEN = 'mockFlowJobToken'

        const mockCertificate: KubernetesCertificate = {
            type: '',
            kubeConfig: '',
            miranaProxy: '',
            jwtToken: ''
        }
        getKubernetesCertificateStub.resolves(mockCertificate)

        try {
            await getKubernetesCertificate()
            expect.fail('Expected an error to be thrown')
        } catch (error) {
            // @ts-ignore
            expect(error.message).to.include('get KubernetesCertificate but error:')
        }
    })
})
